/**
 * 
 */
package parser;

import gnu.getopt.LongOpt;
import gnu.getopt.Getopt;
import java.io.*;
import java.util.*;

/**
 * @author robin
 * 
 */
public final class CommandLine {

	/**
	 * Two steps to parse passwords: 1. Read in the english dictionary, make a
	 * SortList; 2. For each given string, return parsed words.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		LongOpt[] longopts = new LongOpt[4];
		longopts[0] = new LongOpt("dictpath", LongOpt.REQUIRED_ARGUMENT, null,
				'd');
		longopts[1] = new LongOpt("output", LongOpt.OPTIONAL_ARGUMENT, null,
				'o');
		longopts[2] = new LongOpt("passwords", LongOpt.REQUIRED_ARGUMENT, null,
				'p');
		longopts[3] = new LongOpt("help", LongOpt.OPTIONAL_ARGUMENT, null, 'h');

		Getopt g = new Getopt("PasswordParser", args, "", longopts);
		int c;
		String dictPath = null;
		String passwordPath = null;
		String output = null;

		// Parsing arguments
		while ((c = g.getopt()) != -1) {
			switch (c) {
			case 'd':
				dictPath = g.getOptarg();
				if (dictPath == null) {
					System.err.println("dictpath must be specified!");
					System.exit(1);
				}
				break;
			case 'o':
				output = g.getOptarg();
				if (output == null) {
					System.err.println("output path must be specified!");
					System.exit(1);
				}
				break;
			case 'p':
				passwordPath = g.getOptarg();
				if (passwordPath == null) {
					System.err.println("passwords must be specified!");
					System.exit(1);
				}
				break;
			case 'h':
				System.out
						.println("Help:\n\tjava PasswordParser --dictpath= --output= --passwords= --help");
				System.exit(0);
			default:
				String arg = g.getOptarg();
				System.out.println("getopt() returned " + (char) c
						+ " the value is " + ((arg != null) ? arg : "null"));
				break;
			}
		}

		try {
			WordSplitter splitter = new WordSplitter(dictPath);
			PasswordProcessor processor = new PasswordProcessor();
			BufferedReader br = new BufferedReader(new FileReader(passwordPath));
			String line;
			while ((line = br.readLine()) != null) {
				Hashtable<String, List<ArrayDeque<Range>>> result = processor
						.processPassword(splitter, line);
				PrintRange(line, result);
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	public static void PrintRange(String s,
			Hashtable<String, List<ArrayDeque<Range>>> result) {
		System.out.print(String.format("The string\"%s\" is parsed: \n", s));
		for (Enumeration<String> keys = result.keys(); keys.hasMoreElements();) {
			String pass = keys.nextElement();
			System.out.printf("\t%s: ", pass);

			List<ArrayDeque<Range>> rangeLists = result.get(pass);
			System.out.print("[");
			for (ArrayDeque<Range> list : rangeLists) {
				System.out.print("(");
				for (Range r : list) {
					System.out.print(pass.substring(r.getBegin(), r.getEnd() + 1));
					System.out.print(" ");
				}
				System.out.print(")");
			}
			System.out.print("]");
			System.out.print("\n\n");
		}
	}

}
